package org.gpp.proj1.test;

import org.gpp.proj1.particle.ParticleCreator;
import org.gpp.proj1.util.test.JMETestDisplayManager;

import com.jme.math.FastMath;
import com.jme.renderer.Renderer;
import com.jme.scene.Controller;
import com.jme.util.LoggingSystem;
import com.jmex.effects.particles.ParticleController;
import com.jmex.effects.particles.ParticleGeometry;
import com.jmex.effects.particles.ParticleLines;
import com.jmex.effects.particles.ParticleMesh;
import com.jmex.effects.particles.ParticlePoints;
import com.jmex.effects.particles.SimpleParticleInfluenceFactory;

import easyaccept.EasyAccept;

/**
 * 
 * @author Gustavo de Farias
 */
public class ParticleFacade {
	
	ParticleGeometry particle;
	
	/**
	 * 
	 */
	public ParticleFacade() {
		// Disabling logging
		LoggingSystem.getLoggingSystem().loggerOn( false );
		
		JMETestDisplayManager.initJME();
	}
	
	public void loadParticle(String file) {
		this.particle = ParticleCreator.createParticle(file);
	}
	
	public String getParticleGeometry() {
		return this.particle instanceof ParticleMesh ? "mesh" :
			   this.particle instanceof ParticlePoints ? "point" : 
			   this.particle instanceof ParticleLines ? "line" : "none"; 
	}
	
	public boolean isVelocityAligned() {
		return this.particle.isVelocityAligned();
	}
	
	public String getRenderQueueMode() {
		return this.particle.getRenderQueueMode() == Renderer.QUEUE_TRANSPARENT ? "TRANSPARENT".toLowerCase() :
			   this.particle.getRenderQueueMode() == Renderer.QUEUE_INHERIT ? "INHERIT".toLowerCase() :
			   this.particle.getRenderQueueMode() == Renderer.QUEUE_OPAQUE ? "OPAQUE".toLowerCase() :
			   this.particle.getRenderQueueMode() == Renderer.QUEUE_ORTHO ? "ORTHO".toLowerCase() :
			   this.particle.getRenderQueueMode() == Renderer.QUEUE_SKIP ? "SKIP".toLowerCase() : "none";
	}
	
	public float getEmitterTranslation(String coordinate) {
		if (coordinate.toLowerCase().equals("x")) {
			return this.particle.getLocalTranslation().x;
		}
		else if (coordinate.toLowerCase().equals("y")) {
			return this.particle.getLocalTranslation().y;
		}
		else if (coordinate.toLowerCase().equals("z")) {
			return this.particle.getLocalTranslation().z;
		}
		
		throw new RuntimeException("Invalid coordinate");
	}
	
	public float getEmitterRotation(String coordinate) {
		if (coordinate.toLowerCase().equals("x")) {
			return this.particle.getLocalRotation().x;
		}
		else if (coordinate.toLowerCase().equals("y")) {
			return this.particle.getLocalRotation().y;
		}
		else if (coordinate.toLowerCase().equals("z")) {
			return this.particle.getLocalRotation().z;
		}
		
		throw new RuntimeException("Invalid coordinate");
	}
	
	public float getEmitterScale(String coordinate) {
		if (coordinate.toLowerCase().equals("x")) {
			return this.particle.getLocalScale().x;
		}
		else if (coordinate.toLowerCase().equals("y")) {
			return this.particle.getLocalScale().y;
		}
		else if (coordinate.toLowerCase().equals("z")) {
			return this.particle.getLocalScale().z;
		}
		
		throw new RuntimeException("Invalid coordinate");
	}
	
	public String getEmitType() {
		return this.particle.getEmitType() == ParticleGeometry.ET_POINT ? "POINT".toLowerCase() :
			   this.particle.getEmitType() == ParticleGeometry.ET_LINE ? "LINE".toLowerCase() :
			   this.particle.getEmitType() == ParticleGeometry.ET_RING ? "RING".toLowerCase() :
			   this.particle.getEmitType() == ParticleGeometry.ET_RECTANGLE ? "RECTANGLE".toLowerCase() : "none";
	}
	
	/**
	 * @param type
	 * @return
	 */
	public int getParticleNumber( ) {
		return this.particle.getNumParticles();
	}
	
	/**
	 * @param type
	 * @param coordinate
	 * @return
	 */
	public float getGravityForce(String coordinate) {
		
		if (coordinate.toLowerCase().equals("x")) {
			return ((SimpleParticleInfluenceFactory.BasicGravity)this.particle.getInfluences().get(0)).getGravityForce().x;
		}
		else if (coordinate.toLowerCase().equals("y")) {
			return ((SimpleParticleInfluenceFactory.BasicGravity)this.particle.getInfluences().get(0)).getGravityForce().y;
		} 
		else if (coordinate.toLowerCase().equals("z")) {
			return ((SimpleParticleInfluenceFactory.BasicGravity)this.particle.getInfluences().get(0)).getGravityForce().z;
		}
		
		throw new RuntimeException("Invalid coordinate");
	}
	
	public float getWindStrength() {
		return ((SimpleParticleInfluenceFactory.BasicWind)this.particle.getInfluences().get(0)).getStrength();
	}
	
	public boolean getWindVaryRandomly() {
		return ((SimpleParticleInfluenceFactory.BasicWind)this.particle.getInfluences().get(0)).isRandom();
	}
	
	public float getWindDirection(String coordinate) {
		
		if (coordinate.toLowerCase().equals("x")) {
			return ((SimpleParticleInfluenceFactory.BasicWind)this.particle.getInfluences().get(0)).getWindDirection().x;
		}
		else if (coordinate.toLowerCase().equals("y")) {
			return ((SimpleParticleInfluenceFactory.BasicWind)this.particle.getInfluences().get(0)).getWindDirection().y;
		} 
		else if (coordinate.toLowerCase().equals("z")) {
			return ((SimpleParticleInfluenceFactory.BasicWind)this.particle.getInfluences().get(0)).getWindDirection().z;
		}
		
		throw new RuntimeException("Invalid coordinate");
	}
	
	/**
	 * @param type
	 * @param coordinate
	 * @return
	 */
	public float getEmissionDirection(String coordinate) {
		
		if (coordinate.toLowerCase().equals("x")) {
			return this.particle.getEmissionDirection().x;
		}
		else if (coordinate.toLowerCase().equals("y")) {
			return this.particle.getEmissionDirection().y;
		} 
		else if (coordinate.toLowerCase().equals("z")) {
			return this.particle.getEmissionDirection().z;
		}
		
		throw new RuntimeException("Invalid coordinate");
	}
	
	/**
	 * @param type
	 * @return
	 */
	public float getEmissionMaximumAngle( ) {
		return this.particle.getMaximumAngle() / FastMath.PI;
	}
	
	/**
	 * @param type
	 * @return
	 */
	public float getEmissionMinimumAngle( ) {
		return this.particle.getMinimumAngle() / FastMath.PI;
	}
	
	public String getRepeatType() {
		return this.particle.getController(0).getRepeatType() == Controller.RT_CLAMP ? "CLAMP".toLowerCase() :
			   this.particle.getController(0).getRepeatType() == Controller.RT_WRAP ? "WRAP".toLowerCase() :
			   this.particle.getController(0).getRepeatType() == Controller.RT_CYCLE ? "CYCLE".toLowerCase() : "none";
	}

	/**
	 * @param type
	 * @return
	 */
	public float getSpeed() {
		return this.particle.getController(0).getSpeed();
	}
	
	public float getPrecision() {
		return ((ParticleController)this.particle.getController(0)).getPrecision();
	}
	
	/**
	 * @param type
	 * @return
	 */
	public float getParticlesMinimumLifeTime( ) {
		return this.particle.getMinimumLifeTime();
	}
	
	/**
	 * @param type
	 * @return
	 */
	public float getParticlesMaximumLifeTime( ) {
		return this.particle.getMaximumLifeTime();
	}
	
	/**
	 * @param type
	 * @return
	 */
	public float getStartSize( ) {
		return this.particle.getStartSize();
	}
	
	/**
	 * @param type
	 * @return
	 */
	public float getEndSize( ) {
		return this.particle.getEndSize();
	}
	
	/**
	 * @param type
	 * @param component
	 * @return
	 */
	public float getStartColor(String component) {
		
		if (component.toLowerCase().equals("r")) {
			return this.particle.getStartColor().r;
		}
		else if (component.toLowerCase().equals("g")) {
			return this.particle.getStartColor().g;
		} 
		else if (component.toLowerCase().equals("b")) {
			return this.particle.getStartColor().b;
		}
		else if (component.toLowerCase().equals("a")) {
			return this.particle.getStartColor().a;
		}
		
		throw new RuntimeException("Invalid color component.");
	}
	
	/**
	 * @param type
	 * @param component
	 * @return
	 */
	public float getEndColor(String component) {
		
		if (component.toLowerCase().equals("r")) {
			return this.particle.getEndColor().r;
		}
		else if (component.toLowerCase().equals("g")) {
			return this.particle.getEndColor().g;
		} 
		else if (component.toLowerCase().equals("b")) {
			return this.particle.getEndColor().b;
		}
		else if (component.toLowerCase().equals("a")) {
			return this.particle.getEndColor().a;
		}
		
		throw new RuntimeException("Invalid color component.");
	}
	
	/**
	 * @param type
	 * @return
	 */
	public boolean getControlFlow() {
		return ((ParticleController)this.particle.getController(0)).isControlFlow();
	}
	
	/**
	 * @param type
	 * @return
	 */
	public int getReleaseRate() {
		return this.particle.getReleaseRate();
	}
	
	/**
	 * @param type
	 * @return
	 */
	public float getReleaseVariance() {
		return this.particle.getReleaseVariance();
	}
	
	/**
	 * @param type
	 * @return
	 */
	public float getInitialVelocity() {
		return this.particle.getInitialVelocity();
	}
	
	/**
	 * @param type
	 * @return
	 */
	public float getParticleSpinSpeed() {
		return this.particle.getParticleSpinSpeed();
	}
	
	public static void main(String[] args) {
		
		args = new String[]{"org.gpp.proj1.test.ParticleFacade", "./test/particle_factory_test.txt"};
		EasyAccept.main(args);
	}
}